\documentclass[a4paper,10pt]{article}
\usepackage[spanish]{babel} %Paquetes de idioma
\usepackage[latin1]{inputenc} %Paquetes de idioma
\usepackage{graphicx} % Paquete para ingresar gráficos
\usepackage{hyperref}
\usepackage{fancybox}

%Encabezado y Pié de página
\input{EncabezadoyPie.tex}
%Carátula del Trabajo
\title{ \input{Portada.tex} }

\begin{document}
	\maketitle %Hace que el título anterior sea el principal del documento
	\newpage

	\tableofcontents %Esta línea genera un indice a partir de las secciones y subsecciones creadas en el documento
	\newpage

	\section{Resumen}
		El objetivo del presente trabajo consiste en familiarizarnos con las herramientas con las cuales se trabajar\'a en el transcurso de la cursada. Las mismas son:
		\begin{itemize}
			\item Compilador GCC
			\item Shell de Unix
			\item Emulador GXEmul
			\item Sistema de Composici\'on \LaTeX{}
		\end{itemize}
		\vspace{1cm}
 	\section{Introducci\'on Te\'orica}
		\label{sec:InfoTeo}
		Para poner en pr\'actica las herramientas citadas, el presente TP consiste en realizar un programa en C que genera un \emph{volcado octal} de un archivo binario cualquira, y la operaci\'on inversa, es decir, a partir de un archivo con una secuencia octal, genera el archivo binario correspondiente.
A continuaci\'on se explica brevemente los conceptos necesarios para llevar a cabo esta tarea:
		\vspace{0.5cm}
		\subsection{Shell de Unix}
			Un shell es un programa int\'erprete de comandos. Los comandos utilizados en el presente trabajo
			son los siguientes:
			\begin{itemize}
				\item \textbf{(\emph{pipe})}: Toma lo que se encuentra a la izquierda del pipe como la salida estandar (\emph{stdout}) por defecto y lo pasa como
					              entrada estandar (\emph{stdin}) a lo que se este a la derecha del pipe. Puede servir para pasarle a un programa un
						      archivo y que este lo reciba por la entrada estandar
				\item \textbf{echo}: Imprime un texto en (\emph{stdout}).
				\item \textbf{cat}: Con este comando se pueden ver archivos , como as\'i tambi\'en concatenar varios archivos. Al ver un archivo, el
						    mismo se escribe en la salida estandar.
			\end{itemize}
			\vspace{0.5cm}

		\subsection{Compilador GCC}
			GCC es un compilador gratuito, Open Source y multiplataforma que permite compilar c\'odigo C. 
			El mismo es un compilador estandar, es decir, que respeta la norma ISOC99 o ANSI dependiendo de su versi\'on, por lo cual se utilizan las 
			bibliotecas estandar para trabajar con el mismo. En esta asignatura el mismo es de gran utilidad dado que permite tener acceso  al c\'odigo 
			\emph{assembly} equivalente a nuestro programa en C. A continuaci\'on se detallan brevemente algunos par\'ametros que podemos darle al GCC:
			\begin{itemize}
				\item \textbf{-Wall:} Activa todos los warnings.
				\item \textbf{-o file} Almacena la salida del programa en un archivo (\emph{en este caso en file})
				\item \textbf{-O0:} Desactiva las optimizaciones
				\item \textbf{-O3:} Activa todas las optimizaciones
				\item \textbf{-g:} Genera c\'odigo agregando l\'ineas para el \emph{debbugger}
				\item \textbf{-S:} Detiene el compilador luego de generar el c\'odigo \emph{assembly}
				\item \textbf{-mrnames(solo para MIPS):} Indica al compilador que genera la salida utilizando 
									 nombre de registro en lugar de n\'umero de registro
			\end{itemize}
			Para generar c\'odigo assembly en MIPS 32 se debe ejecutar el siguiente comando desde el emulador GXemul:
			\begin{verbatim}
				gcc -Wall -O0 -S -mrnames main.c
			\end{verbatim}
			\vspace{0.5cm}

		\subsection{Emulador GXEmul}
			Es un emulador gratuito y Open Source de la arquitectuca de computadores MIPS. Tiene como ventajas que puede correr algunos sistemas operativos
			sin modificaciones (especialmente \emph{netBSD}), su portabilidad y velocidad de emulaci\'on dado que realiza la traducci\'on binaria en 
			tiempo real. 
			\vspace{0.5cm}
			
	\section{Desarrollo}
		A partir de los conceptos desarrollados en la secci\'on anterior (\ref{sec:InfoTeo}) se procedi\'o a crear un programa en C que genere un volcado octal y su inversa, a continuaci\'on se detalla su funcionamiento y ejecuci\'on:
		\vspace{0.5cm}
		\subsection{Modo de Operaci\'on}
			La aplicaci\'on desarrollada debe recibir una entrada (que puede ser por la entrada standard o por un archivo) y genera una salida (que puede ser a un archivo o a la salida standard). La aplicaci\'on puede ejecutarse en 2 modos, el primero es en modo octal (opci\'on default) en el cual genera un volcado octal de la entrada. El segundo modo es en modo binario el cual recibe una entrada que es un volcado octal valido y genera el archivo binario correspondiente. A continuaci\'on se especifica los comandos que se pueden o deben ingresar para correr el programa:
			\begin{itemize}
				\item \textbf{-h --help:} Muestra el mensaje de ayuda.
				\item \textbf{-V --version:} Muestra la versi\'on del programa.
				\item \textbf{-O --octal:} Modo volcado octal (default). Codifica la entrada binaria en un formato octal.
				\item \textbf{-b --binary:} Modo volcado binario. Codifica la entrada octal en un formato binario.	
				\item \textbf{-i --input:} Ruta al archivo de entrada (default \emph{stdin})
				\item \textbf{-o --output:} Ruta al archivo de salida (default \emph{stdout})							
				\item \textbf{-l --length:} Numero de bytes octales por linea (default 0, sin limitaci\'on).
				\item \textbf{-d --delimiter:} Delimitador entre bytes octales. Puede ser un caracter o un string (default: none)
			\end{itemize}
		\vspace{0.5cm}
		\subsection{Ejemplos}
		     \begin{verbatim}

			$ echo -n "prueba de volcado octal" | ./tp0 -l 3 -d " "
			160 162 165
			145 142 141
			040 144 145
			040 166 157
			154 143 141
			144 157 040
			157 143 164
			141 154 

			$ echo -n "ida y vuelta" | ./tp0 -O -l 2 -d "@" | ./tp0 -b -l 2 -d "@"
			ida y vuelta
		     \end{verbatim}
	\section{Implementaci\'on}
	Algunas decisiones que se tomaron en la implementaci\'on fueron:
	\begin{itemize}
		\item Siempre que se ingrese el parametro de ayuda(-h o --help) o el de version (-V o --version) se ignoraran los demas parametros y se mostrara la ayuda o la version respectivamente y terminara la ejecuci\'on del programa. Por ejemplo:
		\begin{verbatim}
			$ echo -n "test" | ./tp0 -O -l 2 -d "@" -h
		\end{verbatim}
		imprimira e mensaje de ayuda solamente.
		\item Si se ingresa un comando repetido solo se tendr\'a en cuenta al \'ultimo.
		\item Si el valor del parametro de longitud (-l o --length) no es un numero entero positivo se ignorara y se usara el valor default de este.
		\item En el modo binario, el delimitador de bytes octales indicado por parametro no debe ser necesariamente el mismo con el que se ha generado el volcado octal, solo debe tener la misma longitud, ya que solo se trata de un delimitador que no es parte de la salida. Por ejemplo la siguiente ejecuci\'on es
		\begin{verbatim}
		$ echo -n "distinto" | ./tp0 -l 2 -d "#" | ./tp0 -b -l 2 -d "@"
		distinto
		\end{verbatim}
	\end{itemize}


\section{Compilaci\'on y Ejecuci\'on}
	\subsection{Compilaci\'on}
		Para compilar el programa se provee en el CD un archivo Makefile para compilarlo. Para esto desde una terminal en el directorio donde se encuetra el archivo Makefile se debe ejecutar el comando:
	\begin{verbatim}
		$ make
	\end{verbatim}
	Esto generara el archivo ejecutable tp0.
	\subsection{Ejecuci\'on}
		Para ejecutar el programa, una vez compilado, desde la misma terminal se ejecuta el archivo tp0 con los parametros deseados, un ejemplo de ejecuci\'on es:
	\begin{verbatim}
		$ ./tp0 -i /dev/urandom -l 12 -d " "
	\end{verbatim}
\section{Pruebas}
	A continuaci\'on se muestran algunas capturas de pantalla para distintas ejecuciones del programa.
	\begin{itemize}
		\item Imprime la version por pantalla.
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_version.png}
			\end{center}
			
		\item Imprime la ayuda por pantalla.
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_help.png}
			\end{center}
			
		\item Ejecuci\'on de volcado octal con input por stdin y output por stdout
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_1.png}
			\end{center}
		\item Ejecuci\'on de volcado octal con input por stdin y output por stdout, con 4 bytes octales por linea y delimitador @
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_2.png}
			\end{center}
		\item Ejecuci\'on en cadena de volcado octal con input por stdin y tomando el output por stdout de esta como input para convertirlo a binario nuevamente.
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_3.png}
			\end{center}
		\item Se crea un archivo (/tmp/test.bin) y se hace un volcado octal de este a el archivo /tmp/test.oc, luego se muestra la salida utilizando el comando cat y a continuci\'on se hace un vocado binario de este obteniendo el archivo original.
			\begin{center}
				\includegraphics[width=0.8\textwidth]{tp0_4.png}
			\end{center}
	\end{itemize}
	\subsection{Pruebas Automatizadas}
		En el CD adjunto al Trabajo Pr\'actico donde se entregan los fuentes del ejecutable se proporciona un script que ejecuta test automaticos del programa comparando la salida con la salida del comando \emph{od} utilizando el comando \emph{diff}. \\
		El script genera \emph{n} archivos de \emph{b} bytes a partir de /dev/urandom y genera un volcado octal con el comando od y con el programa hecho por nosotros, luego compara ambas salidas con el comando diff. Una vez hecho esto convierte a binario los volcados octales y los compara nuevamente usando diff con los archivos originales.\\
		El script tiene 2 parametros:
		\begin{itemize}
			\item \textbf{-b:} Indica la cantidad de bytes que se usan del archivo /dev/urandom.
			\item \textbf{-n:} Indica la cantidad de loops de ejecuci\'on del script.
		\end{itemize} 
		Un ejemplo de ejecuci\'on del script es:
		\begin{verbatim}
			$ ./test_tp0_6620.sh -b 1024 -n 50
		\end{verbatim}
	\newpage
	\section{Ap\'endice}
	\subsection{C\'odigo Fuente C}
\begin{Verbatim}[fontsize=\tiny]
/*
 ============================================================================
 Name        : tp0_6620.c
 Author      : Agustin Pivetta, Diego Rivas
 Version     : 1.0
 Description : Tp0 66.20: Dump Octal
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <getopt.h>

#define MIN_NUM_ASCII 48
#define MAX_NUM_ASCII 57
#define NEW_LINE '\n'

/*
 * Convierto un byte a byte octal
 */
void bin2oc(unsigned char bin, char octal[]) {
	unsigned int dividendo;
	unsigned char resto;
	unsigned int cociente;
	int i;
	dividendo = bin;
	// Repito solo 3 veces porque ya sé que me va a venir un numero entre 
    // 0 y 255 (como mucho 3 bytes octales)
	for (i = 2; i >= 0; i--) {
		cociente = dividendo / 8;
		resto = dividendo % 8;
		octal[i] = resto;
		dividendo = cociente;
	}
}

/*
 * convierto un byte octal a byte
 */
unsigned char oc2bin(char octal[]) {
	unsigned char bin = 0;
	unsigned char digito;
	unsigned int base;
	int i = 0;
	int j = 0;

	for (i = 0; i < 3; i++) {
		//ASCII -> numero
		switch (octal[i]) {
		case 48: //0
			digito = 0;
			break;
		case 49: //1
			digito = 1;
			break;
		case 50: //2
			digito = 2;
			break;
		case 51: //3
			digito = 3;
			break;
		case 52: //4
			digito = 4;
			break;
		case 53: //5
			digito = 5;
			break;
		case 54: //6
			digito = 6;
			break;
		case 55: //7
			digito = 7;
			break;
		case 56: //8
			digito = 8;
			break;
		case 57: //9
			digito = 9;
			break;
		default:
			fprintf(stderr, "Error, el caracter leido no es un valor de la base octal\n");
			exit(-1);
			break;
		}

		// Calcula la base con la que se tiene q multiplicar el 
        // digito 8^posicion
		base = 1;
		for (j = i; j < 2; j++) {
			base *= 8;
		}

		bin += digito * base;
	}

	return bin;
}

/*
 * Imprimo la ayuda
 */
void printHelp() {
	printf("Usage:\n"
"  tp0 -h\n"
"  tp0 -V\n"
"  tp0 [options]\n"
"Options:\n"
"  -h, --help      Print this information.\n"
"  -V, --version   Print version and quit.\n"
"  -O, --octal     Octal dump mode: encode the input (binary file) in \n"
"                  octal format (default).\n"
"  -b, --binary    Binary mode: decode the input (octal dump file) in\n"
"                  binary format.\n"
"  -i, --input     Path to input file (defaults to stdin).\n"
"  -o, --output    Path to output file (defaults to stdout).\n"
"  -l, --length    Number of octal bytes per line (line length) at the\n"
"                  output in octal dump mode (0 = default = no limit).\n"
"  -d, --delimiter Delimiter between octal bytes. Could be a string, not\n"
"                  only a single byte. Used as delimiter for octal output\n"
"                  and input files (default: none).\n");
        
	
}

/*
 * Imprimo la version
 */
void printVersion() {
	printf("66.20 - TP0: Octal Dump, Versión 1.00\n");;
	return;
}
/*
 * Parseo number y si es un numero entero valido lo casteo a entero
 */
size_t parseInt(const char* number) {
	char len = strlen(number);

	// Si me envían un cero devuelvo 0
	if( (len == 1) && (number[0] == '0') ) return 0;

	size_t i=0;
	// Recorro a m y verifico que cada uno de sus caracteres sean números
	for(i=0; i < len; i++) {
		if ( (number[i] < MIN_NUM_ASCII) || (number[i] > MAX_NUM_ASCII) ) 
		return 0;
	}       

	// Si m es una cadena válida la convierto en un número
	unsigned int aux = 0;
	sscanf(number, "%u", &aux);
	return aux;
}

/* 
 * Leo input, genero un volcado octal y lo escribo en output con length
 * bytes octales por linea con delimitador delimiter
 */
void octalDump(FILE* input, FILE* output, size_t length, char* delimiter){
	unsigned char c;
	char octal[3];
	size_t cont = 0;
	
	c = fgetc(input);
	while (!feof(input)){
		
		bin2oc(c, octal);
		fprintf(output, "%i%i%i", octal[0], octal[1], octal[2]);
		cont++;
		if (cont == length && length != 0){
			fprintf(output, "%c", NEW_LINE);
			cont = 0;
		}else if (delimiter != NULL){
			fprintf(output, "%s", delimiter);
		}
		
		c = fgetc(input);
	}
    
    //imprimo un salto de linea para que quede linda la salida en la terminal
    fprintf(output, "\n");
}

/* 
 * Leo input con length bytes octales por linea con delimitador delimiter, 
 * genero un volcado binario y lo escribo en output 
 */
void binaryDump(FILE* input, FILE* output, size_t length, char* delimiter){
	unsigned char bin;
	char octal[3];
	
	size_t cont = 0;
	size_t i;
	
	fread(octal, sizeof(char), 3, input);
	
	while (!feof(input)){
		cont++;
		
		bin = oc2bin(octal);
		fprintf(output, "%c", bin);
		
		if (length > 0 && cont == length){
			// si llegue a la cantidad de bytes octales por linea indicada 
            // por parametro, ignoro todo lo que sigue hasta el proximo 
            // salto de linealeo hasta el '\n'
			cont = 0;
			while (!feof(input) && fgetc(input) != NEW_LINE){}
		}else if (delimiter != NULL){
			//leo la cantidad de caracteres del delimitador
			for (i = 0; i < strlen(delimiter); i++){
				if (!feof(input)){
					fgetc(input);
				}else{
					break;
				}
			}
		}
		
		fread(octal, sizeof(char), 3, input);
	}
    
    //imprimo un salto de linea para que quede linda la salida en la terminal
    fprintf(output, "\n");
}

/*
 * Abro los archivos de input/outout
 */
FILE* openFile(char* fileName, FILE* default_file, const char* mode){
	FILE* fd;
	if (fileName == NULL){
		fd = default_file;
	}else{
		fd = fopen(fileName, mode);
	}
	
	if (!fd){
		fprintf(stderr, "Error al intentar abrir el archivo");
		exit(-1);
	}
	return fd;
}

int main(int argc, char** argv) {
	// Fuerzo que un error en getopt no se imprima por stderr
	opterr = 0;
	// Indica cuando terminé de procesar todos los argumentos
	int nextOpt = 0;
	// Cadena que lista las opciones cortas válidas
	const char* const opCortas = "hVObi:o:l:d:";
	// Estructura de structs describiendo los valores largos
	const struct option opLargas[] = {
			{"help", no_argument, NULL, 'h'},
			{"version", no_argument, NULL, 'V'},
			{"octal", no_argument, NULL, 'O'},
			{"binary", no_argument, NULL, 'b'},
			{"input", optional_argument, NULL, 'i'},
			{"output", optional_argument, NULL, 'o'},
			{"length", optional_argument, NULL, 'l'},
			{"delimiter", optional_argument, NULL, 'd'},
			{NULL, no_argument, NULL, 0}
	};

	
	// Variable donde recibo el nombre del archivo de entrada
	char* inputFName = NULL;
	// Variable donde recibo el nombre del archivo de salida
	char* outputFName = NULL;
	// Variable donde guardo el modo de ejecucion (1:octal dump mode | 2: binary dump mode)
	char mode = 1;
	// Variable donde guardo la longitud de numeros octal por linea
	size_t length = 0;
	// Variable donde guardo el delimitador de bytes octales
	char* delimiter = NULL;

	while (1) {
		//Leo que me devuelve get_opt
		nextOpt = getopt_long(argc, argv, opCortas, opLargas, NULL);

		if (nextOpt == -1) {
			break;
		}
		
		switch(nextOpt) {
			case 'h': {
				printHelp();
                return 0;
				break;
			}
			
			case 'V': {
				printVersion();
                return 0;
				break;
			}

			case 'O': {
				mode = 1;
				break;
			}
			
			case 'b': {
				mode = 2;
				break;
			}       
			
			case 'i':{
				if (strcmp(optarg, "-") != 0){
					inputFName = malloc(strlen(optarg)+1);
					strcpy(inputFName, optarg);
				}
				break;
			}
			
			case 'o':{
				if (strcmp(optarg, "-") != 0){
					outputFName = malloc(strlen(optarg)+1);
					strcpy(outputFName, optarg);
				}
				break;
			}
			
			case 'l':{
				length = parseInt(optarg);
				break;
			}
			
			case 'd':{				
				delimiter = malloc(strlen(optarg)+1);
				strcpy(delimiter, optarg);
				break;
			}

			default: {
				printHelp();
				exit(-1);
				break;
			}
		}                
	}
	
	FILE* input = openFile(inputFName, stdin, "rb");
	FILE* output = openFile(outputFName, stdout, "wb");
	
	if (mode == 1){
		octalDump(input, output, length, delimiter);
	}else if (mode == 2){
		binaryDump(input, output, length, delimiter);
	}
	
	fclose(input);
	fclose(output);
	
	return 0;
}

\end{Verbatim}
\subsection{C\'odigo Fuente Assembly MIPS}
\begin{Verbatim}[fontsize=\tiny]
	.file	1 "tp0_6620.c"
	.section .mdebug.abi32
	.previous
	.abicalls
	.text
	.align	2
	.globl	bin2oc
	.ent	bin2oc
bin2oc:
	.frame	$fp,40,$ra		# vars= 24, regs= 2/0, args= 0, extra= 8
	.mask	0x50000000,-4
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,40
	.cprestore 0
	sw	$fp,36($sp)
	sw	$gp,32($sp)
	move	$fp,$sp
	move	$v0,$a0
	sw	$a1,44($fp)
	sb	$v0,8($fp)
	lbu	$v0,8($fp)
	sw	$v0,12($fp)
	li	$v0,2			# 0x2
	sw	$v0,24($fp)
$L18:
	lw	$v0,24($fp)
	bgez	$v0,$L21
	b	$L17
$L21:
	lw	$v0,12($fp)
	srl	$v0,$v0,3
	sw	$v0,20($fp)
	lw	$v0,12($fp)
	andi	$v0,$v0,0x7
	sb	$v0,16($fp)
	lw	$v1,44($fp)
	lw	$v0,24($fp)
	addu	$v1,$v1,$v0
	lbu	$v0,16($fp)
	sb	$v0,0($v1)
	lw	$v0,20($fp)
	sw	$v0,12($fp)
	lw	$v0,24($fp)
	addu	$v0,$v0,-1
	sw	$v0,24($fp)
	b	$L18
$L17:
	move	$sp,$fp
	lw	$fp,36($sp)
	addu	$sp,$sp,40
	j	$ra
	.end	bin2oc
	.size	bin2oc, .-bin2oc
	.rdata
	.align	2
$LC0:
	.ascii	"Error, el caracter leido no es un valor de la base octal"
	.ascii	"\n\000"
	.text
	.align	2
	.globl	oc2bin
	.ent	oc2bin
oc2bin:
	.frame	$fp,64,$ra		# vars= 24, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,64
	.cprestore 16
	sw	$ra,56($sp)
	sw	$fp,52($sp)
	sw	$gp,48($sp)
	move	$fp,$sp
	sw	$a0,64($fp)
	sb	$zero,24($fp)
	sw	$zero,32($fp)
	sw	$zero,36($fp)
	sw	$zero,32($fp)
$L23:
	lw	$v0,32($fp)
	slt	$v0,$v0,3
	bne	$v0,$zero,$L26
	b	$L24
$L26:
	lw	$v1,64($fp)
	lw	$v0,32($fp)
	addu	$v0,$v1,$v0
	lb	$v0,0($v0)
	addu	$v0,$v0,-48
	sw	$v0,40($fp)
	lw	$v1,40($fp)
	sltu	$v0,$v1,10
	beq	$v0,$zero,$L38
	lw	$v0,40($fp)
	sll	$v1,$v0,2
	la	$v0,$L39
	addu	$v0,$v1,$v0
	lw	$v0,0($v0)
	.cpadd	$v0
	j	$v0
	.rdata
	.align	2
$L39:
	.gpword	$L28
	.gpword	$L29
	.gpword	$L30
	.gpword	$L31
	.gpword	$L32
	.gpword	$L33
	.gpword	$L34
	.gpword	$L35
	.gpword	$L36
	.gpword	$L37
	.text
$L28:
	sb	$zero,25($fp)
	b	$L27
$L29:
	li	$v0,1			# 0x1
	sb	$v0,25($fp)
	b	$L27
$L30:
	li	$v0,2			# 0x2
	sb	$v0,25($fp)
	b	$L27
$L31:
	li	$v0,3			# 0x3
	sb	$v0,25($fp)
	b	$L27
$L32:
	li	$v0,4			# 0x4
	sb	$v0,25($fp)
	b	$L27
$L33:
	li	$v0,5			# 0x5
	sb	$v0,25($fp)
	b	$L27
$L34:
	li	$v0,6			# 0x6
	sb	$v0,25($fp)
	b	$L27
$L35:
	li	$v0,7			# 0x7
	sb	$v0,25($fp)
	b	$L27
$L36:
	li	$v0,8			# 0x8
	sb	$v0,25($fp)
	b	$L27
$L37:
	li	$v0,9			# 0x9
	sb	$v0,25($fp)
	b	$L27
$L38:
	la	$a0,__sF+176
	la	$a1,$LC0
	la	$t9,fprintf
	jal	$ra,$t9
	li	$a0,-1			# 0xffffffffffffffff
	la	$t9,exit
	jal	$ra,$t9
$L27:
	li	$v0,1			# 0x1
	sw	$v0,28($fp)
	lw	$v0,32($fp)
	sw	$v0,36($fp)
$L40:
	lw	$v0,36($fp)
	slt	$v0,$v0,2
	bne	$v0,$zero,$L43
	b	$L41
$L43:
	lw	$v0,28($fp)
	sll	$v0,$v0,3
	sw	$v0,28($fp)
	lw	$v0,36($fp)
	addu	$v0,$v0,1
	sw	$v0,36($fp)
	b	$L40
$L41:
	lbu	$v1,25($fp)
	lw	$v0,28($fp)
	mult	$v1,$v0
	mflo	$v0
	lbu	$v1,24($fp)
	addu	$v0,$v1,$v0
	sb	$v0,24($fp)
	lw	$v0,32($fp)
	addu	$v0,$v0,1
	sw	$v0,32($fp)
	b	$L23
$L24:
	lbu	$v0,24($fp)
	move	$sp,$fp
	lw	$ra,56($sp)
	lw	$fp,52($sp)
	addu	$sp,$sp,64
	j	$ra
	.end	oc2bin
	.size	oc2bin, .-oc2bin
	.rdata
	.align	2
$LC1:
	.ascii	"Usage:\n"
	.ascii	"  tp0 -h\n"
	.ascii	"  tp0 -V\n"
	.ascii	"  tp0 [options]\n"
	.ascii	"Options:\n"
	.ascii	"  -h, --help      Print this information.\n"
	.ascii	"  -V, --version   Print version and quit.\n"
	.ascii	"  -O, --octal     Octal dump mode: encode the input (bin"
	.ascii	"ary file) in \n"
	.ascii	"                  octal format (default).\n"
	.ascii	"  -b, --binary    Binary mode: decode the input (octal d"
	.ascii	"ump file) in\n"
	.ascii	"                  binary format.\n"
	.ascii	"  -i, --input     Path to input file (defaults to stdin)"
	.ascii	".\n"
	.ascii	"  -o, --output    Path to output file (defaults to stdou"
	.ascii	"t).\n"
	.ascii	"  -l, --length    Number of octal bytes per line (line l"
	.ascii	"ength) at the\n"
	.ascii	"                  output in octal dump mode (0 = default"
	.ascii	" = no limit).\n"
	.ascii	"  -d, --delimiter Delimiter between octal bytes. Could b"
	.ascii	"e a string, not\n"
	.ascii	"                  only a single byte. Used as delimiter "
	.ascii	"for octal output\n"
	.ascii	"                  and input files (default: none).\n\000"
	.text
	.align	2
	.globl	printHelp
	.ent	printHelp
printHelp:
	.frame	$fp,40,$ra		# vars= 0, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,40
	.cprestore 16
	sw	$ra,32($sp)
	sw	$fp,28($sp)
	sw	$gp,24($sp)
	move	$fp,$sp
	la	$a0,$LC1
	la	$t9,printf
	jal	$ra,$t9
	move	$sp,$fp
	lw	$ra,32($sp)
	lw	$fp,28($sp)
	addu	$sp,$sp,40
	j	$ra
	.end	printHelp
	.size	printHelp, .-printHelp
	.rdata
	.align	2
$LC2:
	.ascii	"66.20 - TP0: Octal Dump, Versi\303\263n 1.00\n\000"
	.text
	.align	2
	.globl	printVersion
	.ent	printVersion
printVersion:
	.frame	$fp,40,$ra		# vars= 0, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,40
	.cprestore 16
	sw	$ra,32($sp)
	sw	$fp,28($sp)
	sw	$gp,24($sp)
	move	$fp,$sp
	la	$a0,$LC2
	la	$t9,printf
	jal	$ra,$t9
	move	$sp,$fp
	lw	$ra,32($sp)
	lw	$fp,28($sp)
	addu	$sp,$sp,40
	j	$ra
	.end	printVersion
	.size	printVersion, .-printVersion
	.rdata
	.align	2
$LC3:
	.ascii	"%u\000"
	.text
	.align	2
	.globl	parseInt
	.ent	parseInt
parseInt:
	.frame	$fp,56,$ra		# vars= 16, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,56
	.cprestore 16
	sw	$ra,48($sp)
	sw	$fp,44($sp)
	sw	$gp,40($sp)
	move	$fp,$sp
	sw	$a0,56($fp)
	lw	$a0,56($fp)
	la	$t9,strlen
	jal	$ra,$t9
	sb	$v0,24($fp)
	lb	$v1,24($fp)
	li	$v0,1			# 0x1
	bne	$v1,$v0,$L47
	lw	$v0,56($fp)
	lb	$v1,0($v0)
	li	$v0,48			# 0x30
	bne	$v1,$v0,$L47
	sw	$zero,36($fp)
	b	$L46
$L47:
	sw	$zero,28($fp)
	sw	$zero,28($fp)
$L48:
	lb	$v0,24($fp)
	lw	$v1,28($fp)
	sltu	$v0,$v1,$v0
	bne	$v0,$zero,$L51
	b	$L49
$L51:
	lw	$v1,56($fp)
	lw	$v0,28($fp)
	addu	$v0,$v1,$v0
	lb	$v0,0($v0)
	slt	$v0,$v0,48
	bne	$v0,$zero,$L53
	lw	$v1,56($fp)
	lw	$v0,28($fp)
	addu	$v0,$v1,$v0
	lb	$v0,0($v0)
	slt	$v0,$v0,58
	beq	$v0,$zero,$L53
	b	$L50
$L53:
	sw	$zero,36($fp)
	b	$L46
$L50:
	lw	$v0,28($fp)
	addu	$v0,$v0,1
	sw	$v0,28($fp)
	b	$L48
$L49:
	sw	$zero,32($fp)
	addu	$v0,$fp,32
	lw	$a0,56($fp)
	la	$a1,$LC3
	move	$a2,$v0
	la	$t9,sscanf
	jal	$ra,$t9
	lw	$v0,32($fp)
	sw	$v0,36($fp)
$L46:
	lw	$v0,36($fp)
	move	$sp,$fp
	lw	$ra,48($sp)
	lw	$fp,44($sp)
	addu	$sp,$sp,56
	j	$ra
	.end	parseInt
	.size	parseInt, .-parseInt
	.rdata
	.align	2
$LC4:
	.ascii	"%i%i%i\000"
	.align	2
$LC5:
	.ascii	"%c\000"
	.align	2
$LC6:
	.ascii	"%s\000"
	.align	2
$LC7:
	.ascii	"\n\000"
	.text
	.align	2
	.globl	octalDump
	.ent	octalDump
octalDump:
	.frame	$fp,72,$ra		# vars= 24, regs= 3/0, args= 24, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,72
	.cprestore 24
	sw	$ra,64($sp)
	sw	$fp,60($sp)
	sw	$gp,56($sp)
	move	$fp,$sp
	sw	$a0,72($fp)
	sw	$a1,76($fp)
	sw	$a2,80($fp)
	sw	$a3,84($fp)
	sw	$zero,48($fp)
	lw	$a0,72($fp)
	la	$t9,fgetc
	jal	$ra,$t9
	sb	$v0,32($fp)
$L55:
	lw	$v0,72($fp)
	lhu	$v0,12($v0)
	srl	$v0,$v0,5
	andi	$v0,$v0,0x1
	beq	$v0,$zero,$L57
	b	$L56
$L57:
	lbu	$v0,32($fp)
	addu	$v1,$fp,40
	move	$a0,$v0
	move	$a1,$v1
	la	$t9,bin2oc
	jal	$ra,$t9
	lb	$v1,40($fp)
	lb	$a3,41($fp)
	lb	$v0,42($fp)
	sw	$v0,16($sp)
	lw	$a0,76($fp)
	la	$a1,$LC4
	move	$a2,$v1
	la	$t9,fprintf
	jal	$ra,$t9
	lw	$v0,48($fp)
	addu	$v0,$v0,1
	sw	$v0,48($fp)
	lw	$v1,48($fp)
	lw	$v0,80($fp)
	bne	$v1,$v0,$L58
	lw	$v0,80($fp)
	beq	$v0,$zero,$L58
	lw	$a0,76($fp)
	la	$a1,$LC5
	li	$a2,10			# 0xa
	la	$t9,fprintf
	jal	$ra,$t9
	sw	$zero,48($fp)
	b	$L59
$L58:
	lw	$v0,84($fp)
	beq	$v0,$zero,$L59
	lw	$a0,76($fp)
	la	$a1,$LC6
	lw	$a2,84($fp)
	la	$t9,fprintf
	jal	$ra,$t9
$L59:
	lw	$a0,72($fp)
	la	$t9,fgetc
	jal	$ra,$t9
	sb	$v0,32($fp)
	b	$L55
$L56:
	lw	$a0,76($fp)
	la	$a1,$LC7
	la	$t9,fprintf
	jal	$ra,$t9
	move	$sp,$fp
	lw	$ra,64($sp)
	lw	$fp,60($sp)
	addu	$sp,$sp,72
	j	$ra
	.end	octalDump
	.size	octalDump, .-octalDump
	.align	2
	.globl	binaryDump
	.ent	binaryDump
binaryDump:
	.frame	$fp,64,$ra		# vars= 24, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,64
	.cprestore 16
	sw	$ra,56($sp)
	sw	$fp,52($sp)
	sw	$gp,48($sp)
	move	$fp,$sp
	sw	$a0,64($fp)
	sw	$a1,68($fp)
	sw	$a2,72($fp)
	sw	$a3,76($fp)
	sw	$zero,40($fp)
	addu	$v0,$fp,32
	move	$a0,$v0
	li	$a1,1			# 0x1
	li	$a2,3			# 0x3
	lw	$a3,64($fp)
	la	$t9,fread
	jal	$ra,$t9
$L62:
	lw	$v0,64($fp)
	lhu	$v0,12($v0)
	srl	$v0,$v0,5
	andi	$v0,$v0,0x1
	beq	$v0,$zero,$L64
	b	$L63
$L64:
	lw	$v0,40($fp)
	addu	$v0,$v0,1
	sw	$v0,40($fp)
	addu	$v0,$fp,32
	move	$a0,$v0
	la	$t9,oc2bin
	jal	$ra,$t9
	sb	$v0,24($fp)
	lbu	$v0,24($fp)
	lw	$a0,68($fp)
	la	$a1,$LC5
	move	$a2,$v0
	la	$t9,fprintf
	jal	$ra,$t9
	lw	$v0,72($fp)
	beq	$v0,$zero,$L65
	lw	$v1,40($fp)
	lw	$v0,72($fp)
	bne	$v1,$v0,$L65
	sw	$zero,40($fp)
$L66:
	lw	$v0,64($fp)
	lhu	$v0,12($v0)
	srl	$v0,$v0,5
	andi	$v0,$v0,0x1
	bne	$v0,$zero,$L70
	lw	$a0,64($fp)
	la	$t9,fgetc
	jal	$ra,$t9
	move	$v1,$v0
	li	$v0,10			# 0xa
	bne	$v1,$v0,$L66
	b	$L70
$L65:
	lw	$v0,76($fp)
	beq	$v0,$zero,$L70
	sw	$zero,44($fp)
$L72:
	lw	$a0,76($fp)
	la	$t9,strlen
	jal	$ra,$t9
	lw	$v1,44($fp)
	sltu	$v0,$v1,$v0
	bne	$v0,$zero,$L75
	b	$L70
$L75:
	lw	$v0,64($fp)
	lhu	$v0,12($v0)
	srl	$v0,$v0,5
	andi	$v0,$v0,0x1
	bne	$v0,$zero,$L70
	lw	$a0,64($fp)
	la	$t9,fgetc
	jal	$ra,$t9
	lw	$v0,44($fp)
	addu	$v0,$v0,1
	sw	$v0,44($fp)
	b	$L72
$L70:
	addu	$v0,$fp,32
	move	$a0,$v0
	li	$a1,1			# 0x1
	li	$a2,3			# 0x3
	lw	$a3,64($fp)
	la	$t9,fread
	jal	$ra,$t9
	b	$L62
$L63:
	lw	$a0,68($fp)
	la	$a1,$LC7
	la	$t9,fprintf
	jal	$ra,$t9
	move	$sp,$fp
	lw	$ra,56($sp)
	lw	$fp,52($sp)
	addu	$sp,$sp,64
	j	$ra
	.end	binaryDump
	.size	binaryDump, .-binaryDump
	.rdata
	.align	2
$LC8:
	.ascii	"Error al intentar abrir el archivo\000"
	.text
	.align	2
	.globl	openFile
	.ent	openFile
openFile:
	.frame	$fp,48,$ra		# vars= 8, regs= 3/0, args= 16, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,48
	.cprestore 16
	sw	$ra,40($sp)
	sw	$fp,36($sp)
	sw	$gp,32($sp)
	move	$fp,$sp
	sw	$a0,48($fp)
	sw	$a1,52($fp)
	sw	$a2,56($fp)
	lw	$v0,48($fp)
	bne	$v0,$zero,$L79
	lw	$v0,52($fp)
	sw	$v0,24($fp)
	b	$L80
$L79:
	lw	$a0,48($fp)
	lw	$a1,56($fp)
	la	$t9,fopen
	jal	$ra,$t9
	sw	$v0,24($fp)
$L80:
	lw	$v0,24($fp)
	bne	$v0,$zero,$L81
	la	$a0,__sF+176
	la	$a1,$LC8
	la	$t9,fprintf
	jal	$ra,$t9
	li	$a0,-1			# 0xffffffffffffffff
	la	$t9,exit
	jal	$ra,$t9
$L81:
	lw	$v0,24($fp)
	move	$sp,$fp
	lw	$ra,40($sp)
	lw	$fp,36($sp)
	addu	$sp,$sp,48
	j	$ra
	.end	openFile
	.size	openFile, .-openFile
	.rdata
	.align	2
$LC10:
	.ascii	"help\000"
	.align	2
$LC11:
	.ascii	"version\000"
	.align	2
$LC12:
	.ascii	"octal\000"
	.align	2
$LC13:
	.ascii	"binary\000"
	.align	2
$LC14:
	.ascii	"input\000"
	.align	2
$LC15:
	.ascii	"output\000"
	.align	2
$LC16:
	.ascii	"length\000"
	.align	2
$LC17:
	.ascii	"delimiter\000"
	.data
	.align	2
$LC18:
	.word	$LC10
	.word	0
	.word	0
	.word	104
	.word	$LC11
	.word	0
	.word	0
	.word	86
	.word	$LC12
	.word	0
	.word	0
	.word	79
	.word	$LC13
	.word	0
	.word	0
	.word	98
	.word	$LC14
	.word	2
	.word	0
	.word	105
	.word	$LC15
	.word	2
	.word	0
	.word	111
	.word	$LC16
	.word	2
	.word	0
	.word	108
	.word	$LC17
	.word	2
	.word	0
	.word	100
	.word	0
	.word	0
	.word	0
	.word	0
	.globl	memcpy
	.rdata
	.align	2
$LC9:
	.ascii	"hVObi:o:l:d:\000"
	.align	2
$LC19:
	.ascii	"-\000"
	.align	2
$LC20:
	.ascii	"rb\000"
	.align	2
$LC21:
	.ascii	"wb\000"
	.text
	.align	2
	.globl	main
	.ent	main
main:
	.frame	$fp,240,$ra		# vars= 192, regs= 3/0, args= 24, extra= 8
	.mask	0xd0000000,-8
	.fmask	0x00000000,0
	.set	noreorder
	.cpload	$t9
	.set	reorder
	subu	$sp,$sp,240
	.cprestore 24
	sw	$ra,232($sp)
	sw	$fp,228($sp)
	sw	$gp,224($sp)
	move	$fp,$sp
	sw	$a0,240($fp)
	sw	$a1,244($fp)
	sw	$zero,opterr
	sw	$zero,32($fp)
	la	$v0,$LC9
	sw	$v0,36($fp)
	addu	$v0,$fp,40
	la	$v1,$LC18
	move	$a0,$v0
	move	$a1,$v1
	li	$a2,144			# 0x90
	la	$t9,memcpy
	jal	$ra,$t9
	sw	$zero,184($fp)
	sw	$zero,188($fp)
	li	$v0,1			# 0x1
	sb	$v0,192($fp)
	sw	$zero,196($fp)
	sw	$zero,200($fp)
$L83:
	addu	$v0,$fp,40
	sw	$zero,16($sp)
	lw	$a0,240($fp)
	lw	$a1,244($fp)
	lw	$a2,36($fp)
	move	$a3,$v0
	la	$t9,getopt_long
	jal	$ra,$t9
	sw	$v0,32($fp)
	lw	$v1,32($fp)
	li	$v0,-1			# 0xffffffffffffffff
	bne	$v1,$v0,$L86
	b	$L84
$L86:
	lw	$v0,32($fp)
	addu	$v0,$v0,-79
	sw	$v0,216($fp)
	lw	$v1,216($fp)
	sltu	$v0,$v1,33
	beq	$v0,$zero,$L98
	lw	$v0,216($fp)
	sll	$v1,$v0,2
	la	$v0,$L99
	addu	$v0,$v1,$v0
	lw	$v0,0($v0)
	.cpadd	$v0
	j	$v0
	.rdata
	.align	2
$L99:
	.gpword	$L90
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L89
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L91
	.gpword	$L98
	.gpword	$L97
	.gpword	$L98
	.gpword	$L98
	.gpword	$L98
	.gpword	$L88
	.gpword	$L92
	.gpword	$L98
	.gpword	$L98
	.gpword	$L96
	.gpword	$L98
	.gpword	$L98
	.gpword	$L94
	.text
$L88:
	la	$t9,printHelp
	jal	$ra,$t9
	sw	$zero,212($fp)
	b	$L82
$L89:
	la	$t9,printVersion
	jal	$ra,$t9
	sw	$zero,212($fp)
	b	$L82
$L90:
	li	$v0,1			# 0x1
	sb	$v0,192($fp)
	b	$L83
$L91:
	li	$v0,2			# 0x2
	sb	$v0,192($fp)
	b	$L83
$L92:
	lw	$a0,optarg
	la	$a1,$LC19
	la	$t9,strcmp
	jal	$ra,$t9
	beq	$v0,$zero,$L83
	lw	$a0,optarg
	la	$t9,strlen
	jal	$ra,$t9
	addu	$v0,$v0,1
	move	$a0,$v0
	la	$t9,malloc
	jal	$ra,$t9
	sw	$v0,184($fp)
	lw	$a0,184($fp)
	lw	$a1,optarg
	la	$t9,strcpy
	jal	$ra,$t9
	b	$L83
$L94:
	lw	$a0,optarg
	la	$a1,$LC19
	la	$t9,strcmp
	jal	$ra,$t9
	beq	$v0,$zero,$L83
	lw	$a0,optarg
	la	$t9,strlen
	jal	$ra,$t9
	addu	$v0,$v0,1
	move	$a0,$v0
	la	$t9,malloc
	jal	$ra,$t9
	sw	$v0,188($fp)
	lw	$a0,188($fp)
	lw	$a1,optarg
	la	$t9,strcpy
	jal	$ra,$t9
	b	$L83
$L96:
	lw	$a0,optarg
	la	$t9,parseInt
	jal	$ra,$t9
	sw	$v0,196($fp)
	b	$L83
$L97:
	lw	$a0,optarg
	la	$t9,strlen
	jal	$ra,$t9
	addu	$v0,$v0,1
	move	$a0,$v0
	la	$t9,malloc
	jal	$ra,$t9
	sw	$v0,200($fp)
	lw	$a0,200($fp)
	lw	$a1,optarg
	la	$t9,strcpy
	jal	$ra,$t9
	b	$L83
$L98:
	la	$t9,printHelp
	jal	$ra,$t9
	li	$a0,-1			# 0xffffffffffffffff
	la	$t9,exit
	jal	$ra,$t9
$L84:
	lw	$a0,184($fp)
	la	$a1,__sF
	la	$a2,$LC20
	la	$t9,openFile
	jal	$ra,$t9
	sw	$v0,204($fp)
	lw	$a0,188($fp)
	la	$a1,__sF+88
	la	$a2,$LC21
	la	$t9,openFile
	jal	$ra,$t9
	sw	$v0,208($fp)
	lb	$v1,192($fp)
	li	$v0,1			# 0x1
	bne	$v1,$v0,$L100
	lw	$a0,204($fp)
	lw	$a1,208($fp)
	lw	$a2,196($fp)
	lw	$a3,200($fp)
	la	$t9,octalDump
	jal	$ra,$t9
	b	$L101
$L100:
	lb	$v1,192($fp)
	li	$v0,2			# 0x2
	bne	$v1,$v0,$L101
	lw	$a0,204($fp)
	lw	$a1,208($fp)
	lw	$a2,196($fp)
	lw	$a3,200($fp)
	la	$t9,binaryDump
	jal	$ra,$t9
$L101:
	lw	$a0,204($fp)
	la	$t9,fclose
	jal	$ra,$t9
	lw	$a0,208($fp)
	la	$t9,fclose
	jal	$ra,$t9
	sw	$zero,212($fp)
$L82:
	lw	$v0,212($fp)
	move	$sp,$fp
	lw	$ra,232($sp)
	lw	$fp,228($sp)
	addu	$sp,$sp,240
	j	$ra
	.end	main
	.size	main, .-main
	.ident	"GCC: (GNU) 3.3.3 (NetBSD nb3 20040520)"

\end{Verbatim}
\end{document}


